#include <gtest/gtest.h>
#include <boost/asio.hpp>
#include <thread>
#include "FTPServer.hpp"

class FTPServerTest : public ::testing::Test
{
protected:
    void SetUp() override
    {
        // 创建IO上下文和服务器实例
        io_context = std::make_unique<boost::asio::io_context>();
        server = std::make_unique<FTPServer>(*io_context, 2121); // 使用测试端口

        // 启动服务器线程
        server_thread = std::thread([this]()
                                    { io_context->run(); });
    }

    void TearDown() override
    {
        // 停止IO上下文并等待线程结束
        io_context->stop();
        if (server_thread.joinable())
        {
            server_thread.join();
        }
    }

    std::unique_ptr<boost::asio::io_context> io_context;
    std::unique_ptr<FTPServer> server;
    std::thread server_thread;
};

// 测试服务器是否接受基本连接
TEST_F(FTPServerTest, BasicAccept)
{
    // 创建客户端socket
    boost::asio::ip::tcp::socket client(*io_context);

    // 连接到服务器
    client.connect(boost::asio::ip::tcp::endpoint(
        boost::asio::ip::make_address("127.0.0.1"), 2121));

    // 验证连接是否成功
    EXPECT_TRUE(client.is_open());

    // 关闭客户端连接
    client.close();
}

// 测试服务器响应
TEST_F(FTPServerTest, ServerResponse)
{
    // 创建客户端socket
    boost::asio::ip::tcp::socket client(*io_context);

    // 连接到服务器
    client.connect(boost::asio::ip::tcp::endpoint(
        boost::asio::ip::make_address("127.0.0.1"), 2121));

    // 读取服务器欢迎消息
    boost::asio::streambuf buffer;
    boost::asio::read_until(client, buffer, "\r\n");

    // 验证欢迎消息格式
    std::istream stream(&buffer);
    std::string response;
    std::getline(stream, response);

    // 期望响应格式: "220 FTP Server Ready\r\n"
    EXPECT_TRUE(response.find("220") == 0); // 以220开头
    EXPECT_TRUE(response.find("FTP Server Ready") != std::string::npos);

    // 关闭客户端连接
    client.close();
}

// 测试服务器并发连接
TEST_F(FTPServerTest, ConcurrentConnections)
{
    const int num_connections = 5;
    std::vector<std::unique_ptr<boost::asio::ip::tcp::socket>> clients;

    // 创建多个客户端连接
    for (int i = 0; i < num_connections; ++i)
    {
        auto client = std::make_unique<boost::asio::ip::tcp::socket>(*io_context);
        client->connect(boost::asio::ip::tcp::endpoint(
            boost::asio::ip::make_address("127.0.0.1"), 2121));
        clients.push_back(std::move(client));
    }

    // 验证所有连接都成功
    for (const auto &client : clients)
    {
        EXPECT_TRUE(client->is_open());
    }

    // 关闭所有连接
    for (auto &client : clients)
    {
        client->close();
    }
}

// 测试服务器命令处理
TEST_F(FTPServerTest, CommandHandling)
{
    // 创建客户端socket
    boost::asio::ip::tcp::socket client(*io_context);

    // 连接到服务器
    client.connect(boost::asio::ip::tcp::endpoint(
        boost::asio::ip::make_address("127.0.0.1"), 2121));

    // 读取服务器欢迎消息
    boost::asio::streambuf welcome_buffer;
    boost::asio::read_until(client, welcome_buffer, "\r\n");

    // 发送USER命令
    std::string command = "USER test\r\n";
    boost::asio::write(client, boost::asio::buffer(command));

    // 读取响应
    boost::asio::streambuf response_buffer;
    boost::asio::read_until(client, response_buffer, "\r\n");

    // 验证响应
    std::istream response_stream(&response_buffer);
    std::string response;
    std::getline(response_stream, response);

    // 期望响应格式: "331 Password required for test\r\n"
    EXPECT_TRUE(response.find("331") == 0); // 以331开头
    EXPECT_TRUE(response.find("Password required for test") != std::string::npos);

    // 关闭客户端连接
    client.close();
}
